package com.vf.cloud.paas.app.agent.common.scheduled;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.jfinal.kit.StrKit;
import com.sun.management.OperatingSystemMXBean;
import com.vf.cloud.paas.app.agent.common.util.GpuUtil;
import com.vf.cloud.paas.common.cirrus.Cirrus;
import com.vf.cloud.paas.common.vo.DiskInfo;
import com.vf.cloud.paas.common.vo.GpuInfo;
import com.vf.cloud.paas.common.vo.OsInfo;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;

@SuppressWarnings("restriction")
@Component
@EnableScheduling
public class SystemScheduled {
	@Value("${agent.enabled}")
	private boolean agentEnabled;
	@Value("${agent.install.path}")
	private String installPath;
	@Value("${agent.project.path}")
	private String projectPath;

	@Scheduled(fixedRate = 60000)
	@Async
	public void scheduled() {
		if (agentEnabled) {
			if (Cirrus.isRenderClientConnectedCompleted) {
				try {
					OsInfo osInfo = new OsInfo();

					SystemInfo systemInfo = new SystemInfo();
					OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
					// MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
					// 椎内存使用情况
					// MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();

//					// 初始的总内存
					// long initTotalMemorySize = memoryUsage.getInit();
//					// 最大可用内存
					// long maxMemorySize = memoryUsage.getMax();
//					// 已使用的内存
					// long usedMemorySize = memoryUsage.getUsed();

					// 操作系统
					// String osName = System.getProperty("os.name");
					// 总的物理内存
					String totalMemorySize = new DecimalFormat("#.##")
							.format(osmxb.getTotalPhysicalMemorySize() / 1024.0 / 1024 / 1024) + "G";
					// 剩余的物理内存
					String freePhysicalMemorySize = new DecimalFormat("#.##")
							.format(osmxb.getFreePhysicalMemorySize() / 1024.0 / 1024 / 1024) + "G";
					// 已使用的物理内存
					String usedMemory = new DecimalFormat("#.##")
							.format((osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / 1024.0
									/ 1024 / 1024)
							+ "G";

					osInfo.setMemoryTotal(totalMemorySize);
					osInfo.setMemoryFree(freePhysicalMemorySize);
					osInfo.setMemoryUsed(usedMemory);
					List<GpuInfo> gpuInfos = GpuUtil.getGpuInfos(installPath);
					osInfo.setGpuTotal(gpuInfos.size() + "");
					osInfo.setGpuInfos(gpuInfos);

					// 获得线程总数
					ThreadGroup parentThread;
					for (parentThread = Thread.currentThread().getThreadGroup(); parentThread
							.getParent() != null; parentThread = parentThread.getParent()) {
					}

					// int totalThread = parentThread.activeCount();

					// 磁盘使用情况
					File[] files = File.listRoots();
					List<DiskInfo> diskInfos = new LinkedList<DiskInfo>();
					DiskInfo diskInfo;

					long totalSpace = 0;
					long freeSpace = 0;
					long usableSpace = 0;
					for (File file : files) {
						String path = file.getPath();
//						System.err.println(path + "总:" + total + ",可用空间:" + un + ",空闲空间:" + free);
//						System.err.println("=============================================");
						if (StrKit.equals(projectPath.trim().substring(0, 1), path.trim().substring(0, 1))) {
							diskInfo = new DiskInfo();
							totalSpace += file.getTotalSpace();
							String total = new DecimalFormat("#.#")
									.format(file.getTotalSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
							String free = new DecimalFormat("#.#")
									.format(file.getFreeSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
							freeSpace += file.getFreeSpace();
							String un = new DecimalFormat("#.#")
									.format(file.getUsableSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
							usableSpace += file.getUsableSpace();
							diskInfo.setPath(path);
							diskInfo.setTotal(total);
							diskInfo.setFree(free);
							diskInfo.setUn(un);
							diskInfos.add(diskInfo);
							break;
						}
					}

					osInfo.setDiskTotal(new DecimalFormat("#.#").format(totalSpace * 1.0 / 1024 / 1024 / 1024) + "G");
					osInfo.setDiskFree(new DecimalFormat("#.#").format(freeSpace * 1.0 / 1024 / 1024 / 1024) + "G");
					osInfo.setDiskUsable(new DecimalFormat("#.#").format(usableSpace * 1.0 / 1024 / 1024 / 1024) + "G");
//					String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
//							.format(new Date(ManagementFactory.getRuntimeMXBean().getStartTime()));
//					System.err.println("程序启动时间:" + format);
//					System.err.println("操作系统:" + osName);
//					System.err.println("pid:" + System.getProperty("PID"));
//					System.err.println("cpu核数:" + Runtime.getRuntime().availableProcessors());
//					
					osInfo.setDiskInfos(diskInfos);

					printlnCpuInfo(systemInfo, osInfo);
					Cirrus.renderClient.sendOsInfo(osInfo);
//					System.err.println("JAVA_HOME:" + System.getProperty("java.home"));
//					System.err.println("JAVA_VERSION:" + System.getProperty("java.version"));
//					System.err.println("USER_HOME:" + System.getProperty("user.home"));
//					System.err.println("USER_NAME:" + System.getProperty("user.name"));
//					System.err.println("初始的总内存(JVM):"
//							+ new DecimalFormat("#.#").format(initTotalMemorySize * 1.0 / 1024 / 1024) + "M");
//					System.err.println(
//							"最大可用内存(JVM):" + new DecimalFormat("#.#").format(maxMemorySize * 1.0 / 1024 / 1024) + "M");
//					System.err.println(
//							"已使用的内存(JVM):" + new DecimalFormat("#.#").format(usedMemorySize * 1.0 / 1024 / 1024) + "M");
//					System.err.println("总的物理内存:" + totalMemorySize);
//					System.err
//							.println("总的物理内存:"
//									+ new DecimalFormat("#.##").format(
//											systemInfo.getHardware().getMemory().getTotal() * 1.0 / 1024 / 1024 / 1024)
//									+ "M");
//					System.err.println("剩余的物理内存:" + freePhysicalMemorySize);
//					System.err
//							.println("剩余的物理内存:"
//									+ new DecimalFormat("#.##").format(
//											systemInfo.getHardware().getMemory().getAvailable() * 1.0 / 1024 / 1024 / 1024)
//									+ "M");
//					System.err.println("已使用的物理内存:" + usedMemory);
//					System.err.println("已使用的物理内存:"
//							+ new DecimalFormat("#.##").format((systemInfo.getHardware().getMemory().getTotal()
//									- systemInfo.getHardware().getMemory().getAvailable()) * 1.0 / 1024 / 1024 / 1024)
//							+ "M");
//					System.err.println("总线程数:" + totalThread);
//					System.err.println("===========================");

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void printlnCpuInfo(SystemInfo systemInfo, OsInfo osInfo) throws InterruptedException {
		CentralProcessor processor = systemInfo.getHardware().getProcessor();
		long[] prevTicks = processor.getSystemCpuLoadTicks();
		// 睡眠1s
		TimeUnit.SECONDS.sleep(1);
		long[] ticks = processor.getSystemCpuLoadTicks();
		long nice = ticks[CentralProcessor.TickType.NICE.getIndex()]
				- prevTicks[CentralProcessor.TickType.NICE.getIndex()];
		long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()]
				- prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
		long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]
				- prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
		long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()]
				- prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
		long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()]
				- prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
		long user = ticks[CentralProcessor.TickType.USER.getIndex()]
				- prevTicks[CentralProcessor.TickType.USER.getIndex()];
		long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()]
				- prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
		long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()]
				- prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
		long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
//		System.err.println("cpu核数:" + processor.getLogicalProcessorCount());
//		System.err.println("cpu系统使用率:" + new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
//		System.err.println("cpu用户使用率:" + new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
//		System.err.println("cpu当前等待率:" + new DecimalFormat("#.##%").format(iowait * 1.0 / totalCpu));
//		System.err.println("cpu当前空闲率:" + new DecimalFormat("#.##%").format(idle * 1.0 / totalCpu));

		osInfo.setCpuTotal(processor.getLogicalProcessorCount() + "");
		osInfo.setCpuSysUsageRate(new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
		osInfo.setCpuUserUsageRate(new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
		osInfo.setCpuWaitingUsageRate(new DecimalFormat("#.##%").format(iowait * 1.0 / totalCpu));
		osInfo.setCpuFreeUsageRate(new DecimalFormat("#.##%").format(idle * 1.0 / totalCpu));

		/// 低版本这两个方法是无参方法,高版本中是需要有参数的
//		long[] ticksArray = { 1, 2, 3, 4, 5, 6, 7, 8 };
//		System.err.format("CPU load: %.1f%% (counting ticks)%n",
//				processor.getSystemCpuLoadBetweenTicks(ticksArray) * 100);
//		System.err.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad(1L) * 100);
//
//		System.err.format("CPU load: %.1f%% (counting ticks)%n",
//				processor.getSystemCpuLoadBetweenTicks(ticksArray) * 100);
//		System.err.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad(1L) * 100);
	}
}
